package com.it.tydic.estate.common.aop;

import java.lang.reflect.Method;
import java.util.Date;

import com.google.gson.Gson;
import com.it.tydic.estate.common.annotation.ControllerDesc;
import com.it.tydic.estate.common.constants.Constants;
import com.it.tydic.estate.common.util.CurrentUtil;
import com.it.tydic.estate.common.util.IPUtil;
import com.it.tydic.estate.common.util.InstaIdGenerator;
import com.it.tydic.estate.module.model.inner.TbDataLog;
import com.it.tydic.estate.module.model.inner.TbUser;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;


@Aspect
@Component
public class WebLogAspect {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	
	   /** 
     * Pointcut 
     * 定义Pointcut，Pointcut的名称为aspectjMethod()，此方法没有返回值和参数 
     * 该方法就是一个标识，不进行调用 
     */  
	@Pointcut("@annotation(com.it.tydic.estate.common.annotation.ControllerDesc)")
    private void aspectjMethod(){};
    
    
    /**  
     * After  
     * 核心业务逻辑退出后（包括正常执行结束和异常退出），执行此Advice 
     * @param joinPoint 
     * @throws ClassNotFoundException 
     */  
    @After(value = "aspectjMethod()")    
    public void afterAdvice(JoinPoint joinPoint) throws ClassNotFoundException {
        String methodDescription = getControllerMethodDescription(joinPoint);
        System.out.println("-----------------after data ---------------log");
        //涉及数据库增删改的操作需要保留操作日志（参考YwConstants）
        //0_描述：涉及数据库变化
        //1_描述：不涉及
        if(!StringUtils.isEmpty(methodDescription)){

            //读取session中的用户
            TbUser user =CurrentUtil.getUser();
            ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = sra.getRequest();
            //请求的IP
            String ip = IPUtil.getIp(request);
            TbDataLog log = new TbDataLog();
            InstaIdGenerator id = new InstaIdGenerator();
            log.setId(id.nextId(6)+"");
            if(user != null){
                log.setUserId(user.getUserId());
                log.setUserName(user.getUserName());
            }else{
                log.setUserId(0+"");
                log.setUserName(0+"");
            }
            String methodName = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()";
            log.setMethodName(methodName);
            log.setMethodDescripe(methodDescription);
            log.setUrl(request.getRequestURI());
            log.setCreateTime(new Date());
            //获取用户请求方法的参数并序列化为JSON格式字符串
            String params = "";
            Gson gson = new Gson();
            if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
                if(methodDescription.contains("add") || methodDescription.contains("update")) {
                    log.setType(0);
                    params = gson.toJson(joinPoint.getArgs()[0]);
                }else if(methodDescription.contains("delete")) {
                    log.setType(2);
                    params = gson.toJson(joinPoint.getArgs()[0]);
                }else if(methodDescription.contains("findDetial")) {
                    log.setType(3);
                    params = gson.toJson(joinPoint.getArgs());
                }
            }
            System.out.println(params);
            log.setMethodParam(params);
            Constants.operationLogQueue.offer(log);
        }
        logger.debug("method after");
        System.out.println(methodDescription);
    	
    }   
 /*   /**  
     * before  
     * 核心业务逻辑退出后（包括正常执行结束和异常退出），执行此Advice 
     * @param joinPoint 
     * @throws ClassNotFoundException 
     *//*  
    @Before(value = "aspectjMethod()")    
    public void beforeAdvice(JoinPoint joinPoint) throws ClassNotFoundException {
    	logger.debug("method before");

    }   */
    
    
    
 
    /** 
     * 获取注解中对方法的描述信息 用于Controller层注解 
     * 
     * @param joinPoint 切点 
     * @return 方法描述 
     * @throws ClassNotFoundException 
     * @throws Exception 
     */  
    public static String getControllerMethodDescription(JoinPoint joinPoint) throws ClassNotFoundException{  
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
        Class targetClass = Class.forName(targetName);  
        Method[] methods = targetClass.getMethods();  
        String description = "";  
        for (Method method : methods) {  
            if (method.getName().equals(methodName)) {  
                Class[] clazzs = method.getParameterTypes();  
                if (clazzs.length == arguments.length) {  
                    description = method.getAnnotation(ControllerDesc.class).description();
                    break;  
                }  
            }  
        }  
        return description;  
    }
	
}
